package fetzu.app;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.EventObject;
import java.util.TimeZone;
import java.util.concurrent.ExecutionException;

import javax.swing.ActionMap;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.oauth.OAuthException;

import org.jdesktop.application.Action;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.Task;

import fetzu.app.FireEagleService.AuthenticateTask;
import fetzu.app.FireEagleService.QueryTimeZoneTask;

/* Copyright 2008 Turadg Aleahmad
 *
 * Licensed under the GNU Public License, v3
 */

/**
 * 
 * 
 * @author Turadg Aleahmad
 * 
 */
public class NotReadyForPrimeTime extends SingleFrameApplication {
	JPanel mainPanel;
	JButton btnShowFireEagleTz;
	JTextField txtShowFireEagleTz;

	private static final long DEFAULT_PERIOD = 10 * 1000;

	private JButton exitButton;
	protected final FireEagleService feService = new FireEagleService();
	private JTextField txtShowNetworkTz;
	private JButton btnShowNetworkTz;
	private JButton btnAuthenticateFireEagle;

	static synchronized void syncTimezones(String feTimezone, String tzSource) {
		// FIXME this getDefault() will return the same thing independent of the
		// system once the JVM starts
		String systemTimezone = TimeZone.getDefault().getID().intern();
		System.out.println("\n\ntimezone from " + tzSource + ":" + feTimezone);
		System.out.println("timezone from Java: " + systemTimezone);

		if (feTimezone != systemTimezone) {
			String message = tzSource + " says you're in " + feTimezone
					+ "\nbut your system is set to " + systemTimezone
					+ ".\n\nWould you like to update your system?";

			// default icon, custom title
			int n = JOptionPane.showConfirmDialog(null, message,
					"Time Zone Changed", JOptionPane.YES_NO_OPTION);

			if (n == JOptionPane.YES_OPTION) {
				TimeZoneManager.setSystemTimeZone(feTimezone);
				JOptionPane.showMessageDialog(null, "System time zone is now "
						+ feTimezone, "System Updated",
						JOptionPane.INFORMATION_MESSAGE);
			} else {
				System.out.println("user refused timezone update");
			}
		} else
			System.out.println("same timezone");
	}

	public static void main(String[] args) throws IOException, OAuthException,
			URISyntaxException {
		Application.launch(NotReadyForPrimeTime.class, args);
	}

	@Override
	protected void startup() {
		// Retrieve and set Actions.
		ActionMap actions = getContext().getActionMap(this);

		// scheduleUpdater(DEFAULT_PERIOD);

		btnAuthenticateFireEagle = new JButton();
		btnAuthenticateFireEagle.setName("btnAuthenticateFireEagle");
		btnAuthenticateFireEagle
				.setAction(actions.get("authenticateFireEagle"));
		btnAuthenticateFireEagle.setEnabled(!feService.isAuthenticated());
		
		btnShowFireEagleTz = new JButton();
		btnShowFireEagleTz.setName("btnShowFireEagleTz");
		btnShowFireEagleTz.setAction(actions.get("updateFireEagleTz"));
		txtShowFireEagleTz = new JTextField();
		txtShowFireEagleTz.setName("txtShowFireEagleTz");

		btnShowNetworkTz = new JButton();
		btnShowNetworkTz.setName("btnShowNetworkTz");
		btnShowNetworkTz.setAction(actions.get("updateNetworkTz"));
		txtShowNetworkTz = new JTextField();
		txtShowNetworkTz.setName("txtShowNetworkTz");

		exitButton = new JButton();
		exitButton.setName("exitButton");
		exitButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				exit(e);
			}

		});
		addExitListener(new ExitListener() {
			public boolean canExit(EventObject e) {
				boolean bOkToExit = false;
				Component source = (Component) e.getSource();
				bOkToExit = JOptionPane.showConfirmDialog(source,
						"Do you really want to quit?", "Quit Confirmation",
						JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
				return bOkToExit;
			}

			public void willExit(EventObject event) {

			}
		});

		// lay out components
		mainPanel = new JPanel();
		mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
		mainPanel.add(btnAuthenticateFireEagle);

		JPanel fePanel = new JPanel();
		fePanel.add(btnShowFireEagleTz);
		fePanel.add(txtShowFireEagleTz);
		mainPanel.add(fePanel);

		JPanel ipPanel = new JPanel();
		ipPanel.add(btnShowNetworkTz);
		ipPanel.add(txtShowNetworkTz);
		mainPanel.add(ipPanel);

		mainPanel.add(exitButton);
		show(mainPanel);
	}

	/*
	 * private void scheduleUpdater(long period) { // FIXME this thread doesn't
	 * get the latest system time zone because JVM // doesn't update TimerTask
	 * queryTask = new TimerTask() {
	 * 
	 * @Override public void run() { feService.queryFireEagle(); if
	 * (!feService.fireEagleWorking) { IpLookup.lookup(); String[] possibleIds =
	 * IpLookup.getPossibleIds(); syncTimezones(possibleIds[0], "Your IP
	 * address"); } } };
	 * 
	 * Timer timer = new Timer(); timer.scheduleAtFixedRate(queryTask, 0,
	 * period); }
	 */

	@Action
	public void authenticateFireEagle() {
		final AuthenticateTask task = feService.new AuthenticateTask(this);
		task.execute();
		task.addPropertyChangeListener(new PropertyChangeListener() {

			public void propertyChange(PropertyChangeEvent evt) {
				if (evt.getPropertyName().equals("completed")) {
					if (feService.isAuthenticated())
						btnAuthenticateFireEagle.setEnabled(false);
				}
			}

		});

	}

	@Action
	public void updateNetworkTz() {
		final Task<TimeZone[], Void> task = new IpLookup.Retriever(this);
		task.execute();
		task.addPropertyChangeListener(new PropertyChangeListener() {

			public void propertyChange(PropertyChangeEvent evt) {
				if (evt.getPropertyName().equals("completed")) {
					TimeZone[] timeZones;
					try {
						timeZones = task.get();
						txtShowNetworkTz.setText(timeZones[0].getID());
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (ExecutionException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						txtShowFireEagleTz.setText("error: " + e);
					}
				}
			}

		});
	}

	@Action
	public void updateFireEagleTz() {
		final QueryTimeZoneTask task = feService.new QueryTimeZoneTask(this);
		task.execute();
		task.addPropertyChangeListener(new PropertyChangeListener() {

			public void propertyChange(PropertyChangeEvent evt) {
				if (evt.getPropertyName().equals("completed")) {
					try {
						TimeZone timeZone = task.get();
						txtShowFireEagleTz.setText(timeZone.getID());
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (ExecutionException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						txtShowFireEagleTz.setText("error: " + e);
					}
				}
			}

		});
	}

}
